#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui_c.h>

#pragma execution_character_set("gbk")

using namespace cv;
using namespace std;

//输入图像
String File_Path = "C:\\Users\\1米89叶超\\Desktop\\20230210出差C机数据\\原始数据\\2023_2_10 18_13_38Hi暗场.bin";

//图像保存位置
#define img_path  "./pic/"
#define img_type ".bmp"
#define IMG_WIDTH     6
#define IMG_HEIGHT    64
#define IMG_BITWIDTH  65535      //2^14 14位图像

unsigned short(imagedata[IMG_WIDTH*IMG_HEIGHT]);
unsigned short Hist[IMG_BITWIDTH];

//路径和文件数字
char *filename;
char  *number;

//两种不同的14位转8位映射
Mat  mat14to8(unsigned short *srcData);
Mat img14to8(ushort *in, int rows, int cols);
Mat mat16to8(ushort *srcData, int rows, int cols);

int main()
{
    Mat outputImage(IMG_HEIGHT, IMG_WIDTH, CV_8UC1, Scalar(0));


    //打开文件并确定结尾位置和图片数量
    FILE *pfile;
    pfile = fopen(File_Path.c_str(), "r");
//    if(pfile = fopen(File_Path.c_str(), "r")==NULL)
//    {
//        return false;
//    }
    struct stat statbuf;
    stat(File_Path.c_str(), &statbuf);
    cout << "size:" << statbuf.st_size << "B" << endl;
    int number_size = statbuf.st_size / (sizeof(unsigned short)*IMG_HEIGHT*IMG_WIDTH);
    cout << "pic number:" << number_size << " " << endl;


    for (size_t i = 0; i < number_size; i++)
    {

        fread(imagedata, sizeof(unsigned short), IMG_HEIGHT*IMG_WIDTH, pfile);

//        outputImage = mat14to8(imagedata);
        outputImage = mat16to8(imagedata, IMG_HEIGHT, IMG_WIDTH);
        imshow("BMP", outputImage);
        cout << "deal:" << i << " " << endl;

        //定义保存图片的代码
        filename = (char*)malloc(1000 * sizeof(char));
        number = (char*)malloc(1000 * sizeof(char));
        sprintf(filename, img_path);
        sprintf(number, "%06d", i);
        strcat(filename, number);
        strcat(filename, img_type);
        imwrite(filename, outputImage);
        fseek(pfile,IMG_HEIGHT*IMG_WIDTH*sizeof(unsigned short),SEEK_CUR);
        waitKey(10);
    }
    free(filename);
    free(number);

    return 0;

}

Mat mat16to8(ushort *srcData, int rows, int cols)
{
    for(int i=0;i<rows*cols;i++)
    {
        srcData[i]=srcData[i]/257;
    }
    Mat out(rows, cols, CV_8UC1);
    for (size_t i = 0; i < rows; i++)
    {
        for (size_t j = 0; j < cols; j++)
        {
            out.ptr<uchar>(i)[j] = *(srcData + i*cols + j);
        }
    }
    return out;
}

Mat mat14to8(unsigned short *srcData)
{
    Mat out(IMG_HEIGHT, IMG_WIDTH, CV_8UC1, Scalar(0));

    unsigned int MaxValue = 0, MinValue = 0xffffff;
    float Factor = 1.0, middle = 0.0;

    for (size_t i = 0; i < IMG_HEIGHT*IMG_WIDTH; i++)
    {
        Hist[srcData[i]]++;
    }
    for (size_t i = 0; i < IMG_HEIGHT*IMG_WIDTH; i++)
    {
        if ((MaxValue<*(srcData + i)) && (Hist[*(srcData + i)]>50))
        {
            MaxValue = *(srcData + i);
        }
        else {}
        if ((MinValue>*(srcData + i)) && (Hist[*(srcData + i)]>50))
        {
            MinValue = *(srcData + i);
        }
        else {}
    }
    Factor = 255.0 / (MaxValue - MinValue);
    for (size_t i = 0; i < IMG_HEIGHT; i++)
    {
        for (size_t j = 0; j < IMG_WIDTH; j++)
        {
            middle = (*(srcData + i*IMG_WIDTH + j) - MinValue)*Factor;

            if (*(srcData + i*IMG_WIDTH + j) == 0)
            {
                out.ptr<uchar>(i)[j] = 0;
            }
            else
            {
                if (middle < 0)
                    out.ptr<uchar>(i)[j] = 0;
                else if (middle>255)
                    out.ptr<uchar>(i)[j] = 255;
                else
                    out.ptr<uchar>(i)[j] = (uchar)middle;
            }


        }
    }
    return out;

}

Mat img14to8(ushort *in, int rows, int cols)
{
    Mat out(rows, cols, CV_8UC1);
    int inc = 0, minValue = 0, maxValue = 0;
    double factor = 0.0, middle = 0.0;
    unsigned char hist[640 * 512];
    memset(hist, 0, sizeof(hist));
    for (size_t i = 0; i < rows; i++)
    {
        for (size_t j = 0; j < cols; j++)
        {
            if (in[i*cols + j] > 0 && in[i*cols + j] < 16384)
                hist[in[i*cols + j]] = hist[in[i*cols + j]] + 1;
        }
    }

    for (size_t i = 0; i < 16384; i++)
    {
        if ((inc < 2000) && ((inc + hist[i]) > 1999))
        {
            minValue = i;
            break;
        }
        inc = inc + hist[i];
    }

    inc = 0;
    for (size_t i = 16383; i > 0; i--)
    {
        if ((inc < 2000) && ((inc + hist[i]) > 1999))
        {
            maxValue = i;
            break;
        }
        inc = inc + hist[i];
    }

    maxValue = maxValue + 32;
    minValue = minValue - 32;
    factor = 1.0 / (maxValue - minValue) * 255;

    for (size_t i = 0; i < rows; i++)
    {
        for (size_t j = 0; j < cols; j++)
        {
            if (in[i*cols + j] == 0)
                out.ptr<uchar>(i)[j] = 0;
            else
            {
                middle = (in[i*cols + j] - minValue)*factor;
                if (middle>255)
                    out.ptr<uchar>(i)[j] = 255;
                else if (middle<0)
                    out.ptr<uchar>(i)[j] = 0;
                else
                    out.ptr<uchar>(i)[j] = uchar(middle);
            }
        }
    }

    return out;
}

